#define _CRT_SECURE_NO_WARNINGS 1
#include <algorithm>
#include <map>
#include <cstdio>
#include <functional>
#include <atomic>
#include <iostream>
#include <vector>
#include <list>
#include "string.h"
#include "list.h"
#include <exception>
#include <thread>
#include <mutex>
using namespace std;
using namespace test;

// int main()
// {
//     int x1 = 1;
//     int x2 = {2};
//     int x3{3};
//
//     int* pa1 = new int[4];
//     int* pa2 = new int[4]{1,2,3,4};
//
//     auto il = {10,20,30,40,50};
//     cout << typeid(il).name() << endl;
//
//     initializer_list<int>::iterator it = il.begin();
//     while (it != il.end())
//     {
//         cout << *it << ", ";
//         ++it;
//     }
//     cout << endl;
//
//     test::vector<int> v = {1, 2, 3, 4, 5};
//
//
//     return 0;
// }
//
// class date
// {
// public:
//     date(int year, int month, int day)
//         : _year(year), _month(month), _day(day)
//     {}
//
// private:
//     int _year;
//     int _month;
//     int _day;
//
// };
//
// int main()
// {
//     date d1(2023, 7, 12);
//     date d2 = {2023, 7, 12};
//     date d3{2023, 7, 12};
//     return 0;
// }
//
// int main()
// {
//     int x = 1;
//
//     decltype(x)& rx = x;
//     decltype(x)* px = &x;
//
//     cout << typeid(rx).name() << endl;
//     cout << typeid(px).name() << endl;
//
//     return 0;
// }
//
// int main()
// {
//     int a = 0, b = 0;
//     int* pa = &a;
//
//     int& lr = a;
//     int&& rr = a + b;
//
//     rr += 1;
//     cout << rr << endl;
//
//     const int& clr = a + b;
//     int&& rrm = std::move(a);
//
//     rrm += 1;
//     cout<< rrm << endl;
//
//     cout << typeid(lr).name() << endl;
//     cout << typeid(rr).name() << endl;
//
//     return 0;
// }
//
// void func(int& lra)
// {
//     cout << "void func(int& lra)" << endl;
// }
//
// void func(int&& rra)
// {
//     cout << "void func(int&& rra)" << endl;
// }
//
// int main()
// {
//     int a = 0;
//     int b = 1;
//
//     func(a);
//     func(a + b);
//
//     return 0;
// }
//
// test::string func()
// {
//     test::string s("hello");
//     return s;
// }
//
// int main()
// {
//     string ret;
//     ret = func();
//
//     // string s1("hello");
//     // string s2("world");
//
//     // string ret1 = s1;
//     // string ret2 = s1 + s2;
//
//     // string ret3 = std::move(s1);
//
//     return 0;
// }
//
//
// void fun(int&)
// {
//     cout << "void fun(int&)" << endl;
// }
//
// void fun(const int&)
// {
//     cout << "void fun(const int&)" << endl;
// }
//
// void fun(int&&)
// {
//     cout << "void fun(int&&)" << endl;
// }
//
// void fun(const int&&)
// {
//     cout << "void fun(const int&&)" << endl;
// }
//
// template<typename T>
// void imperfect_forward(T&& t)
// {
//     fun(t);
// }
//
// template<typename T>
// void perfect_forward(T&& t)
// {
//     fun(std::forward<T>(t));
// }
//
// // int main()
// // {
// //     int a = 0;
// //     const int b = 0;
// //
// //     perfect_forward(10);
// //
// //     perfect_forward(a);
// //     perfect_forward(std::move(a));
// //     perfect_forward(b);
// //     perfect_forward(std::move(b));
// //
// //     return 0;
// // }
//
// using namespace test;
//
// int main()
// {
//     // list<test::string> lt;
//     //
//     // test::string s = "hello left ref";
//     //
//     // lt.push_back(s);
//     //
//     // lt.push_back(test::string("hello right ref1"));
//     // lt.push_back("hello right ref2");
//
//     test::string s1;
//     s1 = func();
//
//     return 0;
//
// }
//
//
// class Person {
// public:
//     Person(const char* name = "", int age = 18) : _name(name), _age(age)
//     {}
//
//     // #define kbgz 1
//     // #define kbfz 1
//     // #define xg 1
//
// #ifdef kbgz
//     Person(const Person& p) : _name(p._name), _age(p._age)
//     {}
// #endif
//
// #ifdef kbfz
//     Person operator=(const Person& p) {
//         if (this == &p) {
//             Person tmp(p);
//             return tmp;
//         }
//         return *this;
//     }
// #endif
//
// #ifdef xg
//     ~Person()
//     {}
// #endif
//
// private:
//     test::string _name;
//     int _age;
// };
//
// int main()
// {
//     Person p1("hello", 18);
//     Person p2 = std::move(p1);
//     p1 = std::move(p2);
// }
//
// void show_list()
// {
//     cout << endl;
// }
//
// template<class T, class... Args>
// void show_list(const T& val, Args... args)
// {
//     cout << val << " ";
//     show_list(args...);
// }
//
// int main()
// {
//     show_list();
//     show_list('1');
//     show_list('1', 2);
//     show_list('1', 2, "3");
//
//     return 0;
// }
//
// struct goods
// {
//     std::string _name; //名字
//     double _price;//价格
//     int _evaluate;// 评价
//
//     goods (const char* str, double price, int evaluate)
//         : _name(str)
//         , _price(price)
//         , _evaluate(evaluate)
//     {}
// };
//
// struct compare_price_less
// {
//     bool operator()(const goods& g1, const goods& g2)
//     {
//         return g1._price < g2._price;
//     }
// };
//
// struct compare_price_greater
// {
//     bool operator()(const goods& g1, const goods& g2)
//     {
//         return g1._price > g2._price;
//     }
// };
//
// int main()
// {
//     vector<goods> v
//         = {{"pg",2.1,5},{"xj",3,4},{"cz",2.2,3},{"bl",1.5,4}};
//
//     sort(v.begin(), v.end(), [](const goods& g1, const goods& g2) {
//         return g1._price < g2._price;
//     });
//     sort(v.begin(), v.end(), [](const goods& g1, const goods& g2) {
//         return g1._price > g2._price;
//     });
//
//     return 0;
// }
//
// int main()
// {
//     auto add1 = [](int x, int y) -> int {
//         return x + y;
//     };
//
//     cout << typeid(add1).name() << endl;
//
//     add1(1, 2);
//     [](int x, int y)->int{ return x + y; }(1, 2);
//
//     return 0;
// }
//
//
// int main()
// {
//     int x = 1;
//     int y = 0;
//
//     auto swap1 = [](int& x, int& y) {
//         int tmp = x;
//         x = y;
//         y = tmp;
//     };
//
//     swap1(x, y);
//
//     auto swap2 = [&x, &y](){
//         int t = x;
//         x = y;
//         y = t;
//     };
//
//     cout << x << ", " << y << endl;
//
//     return 0;
// }
//
// struct functor {
//     void operator()() {
//         cout << 1 << endl;
//     }
// };
//
// int main()
// {
//     thread t1(func, 10, 1);
//     thread t2(func, 10, 2);
//
//     int n1 = 0, n2 = 0;
//     cin >> n1 >> n2;
//
//     thread t1([&n1](int num) {
//         while (n1--) {
//             cout << num << ":" << n1 << endl;
//         }
//     }, 1);
//     thread t2([&n2](int num) {
//         while (n2--) {
//             cout << num << ":" << n2 << endl;
//         }
//     }, 2);
//
//     int n = 0, m = 0;
//     cin >> n >> m;
//
//     vector<thread> vths(n);
//
//     for (int i = 0; i < vths.size(); i++)
//     {
//         vths[i] = thread([m, i]() mutable { // move pass
//             while (m >= 0) {
//                 cout << i << "->" << m-- << endl;
//             }
//         });
//     }
//
//     for (auto& th : vths)
//     {
//         th.join();
//     }
//
//     auto lamdba = []() {};
//     lamdba();
//     functor();
//     // cout << sizeof(lamdba) << endl;
//     // cout << typeid(lamdba).name() << endl;
//
//     return 0;
// }
//
//
//
// void func1(int n, mutex& mtx)
// {
//     mtx.lock();
//     while (n--)
//     {
//         x++;
//         lt.push_back(x);
//         lt.push_back(x);
//
//         cout << x << endl;
//     }
//     mtx.unlock();
// }
//
// void func2(int n, mutex& mtx)
// {
//     while (n--)
//     {
// 		mtx.lock();
//         x++;
//         lt.push_back(x);
//         lt.push_back(x);
//
//         cout << x << endl;
// 		mtx.unlock();
//     }
// }
//
// int main()
// {
//     list<int> lt;
//     int n = 10000;
//     int x = 0;
//
//     mutex mtx;
//     size_t begin = clock();
//
//     thread t1([&, n]() mutable {
//         mtx.lock();
//         while (n--) {
//             x++;
//         }
//         mtx.unlock();
//     });
//
//     thread t2([&, n]() mutable {
//         while (n--) {
//             mtx.lock();
//             x++;
//             mtx.unlock();
//         }
//     });
//
//     t1.join();
//     t2.join();
//
//     size_t end = clock();
//
//     cout << x << endl;
//     cout << end - begin << endl;
//
//     return 0;
// }
//
// int x = 0;
// recursive_mutex mtx;
//
// void func(int n)
// {
//     if (n == 0)
//         return;
//
//     try
//     {
//         mtx.lock();
//
//         ++x;
//         func(n - 1);
//
//         mtx.unlock();
//
//     }
//     catch (const exception& e)
//     {
//         cout << e.what() << endl;
//     }
// }
//
// template<class Lock>
// class lock_guard
// {
// public:
//     lock_guard(Lock& lk)
//         : _lk(lk)
//     {
//         _lk.lock();
//     }
//
//     ~lock_guard()
//     {
//         _lk.unlock();
//     }
// private:
//     Lock& _lk;
// };
//
// int x = 0;
// mutex mtx;
//
// void func(int n)
// {
//     try
//     {
//         std::lock_guard<mutex> lock(mtx);
//         if (n == 0)
//             return;
//
//         ++x;
//
//         if (rand() % 3 == 0)
//             throw exception("error");
//
//         func(n - 1);
//     }
//     catch (const exception& e)
//     {
//         cout << e.what() << endl;
//     }
// }
//
// int main()
// {
//     thread t1(func, 1000);
//     thread t2(func, 1000);
//
//     t1.join();
//     t2.join();
//
//     cout << x << endl;
//
//     return 0;
// }
//
// int main()
// {
//     atomic<int> i;
//     i++;
//
//     int j = i;
//     printf("%d\n", i.load());
//
//     return 0;
// }
//
// int main()
// {
//     mutex mtx;
//     condition_variable cond;
//     int n = 100;
//     int x = 1;
//
//     thread t1([&, n]() mutable {
//
//         while (n--)
//         {
//             unique_lock<mutex> lock(mtx);
//             while (x % 2 == 0)
//                 cond.wait(lock);
//
//             cout << this_thread::get_id() << ":" << x << endl;
//             ++x;
//
//             cond.notify_one();
//         }
//     });
//
//     thread t2([&, n]() mutable {
//         while (n--)
//         {
//             unique_lock<mutex> lock(mtx);
//             while (x % 2 == 1)
//                 cond.wait(lock);
//
//             cout << this_thread::get_id() << ":" << x << endl;
//             ++x;
//
//             cond.notify_one();
//         }
//     });
//
//     t1.join();
//     t2.join();
//
//     return 0;
// }
//
// // 普通函数
// int func(int a, int b) {
//     return a + b;
// }
// // 仿函数
// struct functor {
//     int operator()(int x, int y) {
//         return x + y;
//     }
// };
// // 非静态成员函数
// struct Plus {
//     int plus(int a, int b) {
//         return a + b;
//     }
// };
// struct Sub {
//     static int sub(int a, int b) {
//         return a + b;
//     }
// };
//
// int main()
// {
//     std::function<int(int, int)> f1 = func;
//     std::function<int(int, int)> f2 = functor();
//     std::function<int(int, int)> f3 = &Sub::sub;
//     std::function<int(int, int)> f4 = [](int, int)->int {return 0;};
//     std::function<int(Plus&, int, int)> f5 = &Plus::plus;
//
//     map<string, function<int(int, int)>> opfunc_map;
//     opfunc_map["hszz"] = f1;
//     opfunc_map["fhs"] = f2;
//     opfunc_map["jtcyhs"] = f3;
//     opfunc_map["lambda"] = f4;
//
//     string s;
//     int op1 = 0, op2 = 0;
//     cin >> s >> op1 >> op2;
//
//     cout << opfunc_map[s](op1, op2) << endl;
//
//     return 0;
// }
//
// struct Plus {
// 	Plus(int i)
//     {}
//     int plus(int a, int b) { return a + b; }
// };
//
// int main()
// {
//     function<int(Plus, int, int)>    f1 = &Plus::plus;
//     f1(Plus(1),1,2);
//     function<int(Plus&, int, int)>   f2 = &Plus::plus;
//     Plus p(1);
//     f2(p,1,2);
//     function<int(Plus*, int, int)>   f3 = &Plus::plus;
//     f3(&p,1,2);
//     function<int(Plus&&, int, int)>   f4 = &Plus::plus;
//     f4(Plus(3),1,2);
//
//     return 0;
// }
//
// void print(int a, int b)
// {
//     cout << a << " " << b << endl;
// }
//
// int main()
// {
//     print(1, 2);
//
//     function<void(int,int)> f1 = bind(print, placeholders::_2, placeholders::_1);
//     auto f2 = bind(print, placeholders::_2, placeholders::_1);
//
//     f1(1, 2);
//     f2(1, 2);
// }
//
// class suber
// {
// public:
//     suber(int rt) : _rt(rt)
//     {}
//
//     int sub(int a, int b)
//     {
//         return (a - b) * _rt;
//     }
// private:
//     int _rt;
//
// };
//
// int main()
// {
//     function<int(suber, int, int)> f = &suber::sub;
//     f(suber(1), 1, 2);
//
//     function<int(int, int)> fsub = bind(&suber::sub, suber(3), placeholders::_1, placeholders::_2);
//     fsub(1, 2);
//
//     return 0;
// }

struct A
{
    virtual void func()
    {

    }
};

struct B : public A
{
    virtual void func()
    {

    }
    int _b = 1;
};

void test_dynamic_cast()
{
    A* pa1 = new A;
    B* pb1 = dynamic_cast<B*>(pa1);

    A* pa2 = new B;
    B* pb2 = dynamic_cast<B*>(pa2);

    cout << "pa1" << pa1 << "\tdynamic_cast: " << pb1 << endl;
    cout << "pa2" << pa2 << "\tdynamic_cast: " << pb2 << endl;
}

int main()
{
    int i = 1;
    double d1 = i; // 隐式类型转换
    double d2 = (double)i; // 显式类型转换
    
    i = d1;
    i = static_cast<int>(d1);

    // int* p = static_cast<int*>(i); //err
    int* p = reinterpret_cast<int*>(i);
    
    volatile const int a = 2;
    int* pa = const_cast<int*>(&a);

    cout << a << endl;
    cout << *pa << endl;

    test_dynamic_cast();



    return 0;
}
